<?php

namespace iBrand\Shop\Server\Service;

use iBrand\Component\Goods\Models\GoodsProduct;
use iBrand\Component\Goods\Models\GoodsSpecRelation;
use iBrand\Component\Goods\Models\SpecsValue;
use iBrand\Component\Goods\Repositories\GoodsRepository;
use iBrand\Component\Order\Models\Order;
use iBrand\Component\Purchase\Models\StockRecord;
use iBrand\Component\Purchase\Repositories\StockRecordRepository;
use iBrand\Shop\Core\Models\O2oGoodsProducts;
use iBrand\Shop\Core\Models\Refund;
use iBrand\Shop\Core\Models\ShopBrandRelation;
use iBrand\Shop\Core\Repositories\O2oGoodsProductsRepository;
use iBrand\Shop\Core\Repositories\O2oGoodsRepository;
use Illuminate\Support\Collection;

class GoodsService
{
    protected $o2oGoodsRepository;
    protected $o2oGoodsProductRepository;
    protected $baseRepository;
    protected $stockRecordRepository;

    public function __construct(O2oGoodsRepository $o2oGoodsRepository,
                                O2oGoodsProductsRepository $o2oGoodsProductsRepository,
                                GoodsRepository $goodsRepository,
                                StockRecordRepository $stockRecordRepository)
    {
        $this->o2oGoodsRepository = $o2oGoodsRepository;
        $this->o2oGoodsProductRepository = $o2oGoodsProductsRepository;
        $this->baseRepository = $goodsRepository;
        $this->stockRecordRepository = $stockRecordRepository;

    }

    public function getStockByGoodsID($id)
    {
        $o2oGoods = $this->o2oGoodsRepository->find($id);

        if (!$o2oGoods) {
            return false;
        }

        $specs = [];
        $stores = [];

        if ($products = $o2oGoods->o2oProducts) {
            //生成库存信息
            $products->each(function ($item, $key) use (&$stores, $o2oGoods) {
                $baseProduct = $item->baseProduct;
                $specArray = $baseProduct->specID;

                asort($specArray);

                $spec_id = implode('-', $specArray);
                $stores[$spec_id]['id'] = $item->id;
                $stores[$spec_id]['store'] = $item->store_nums;

                if ($o2oGoods->is_discount) {
                    $stores[$spec_id]['price'] = $o2oGoods->discount_price;
                } else {
                    $stores[$spec_id]['price'] = $baseProduct->market_price;
                }

                $stores[$spec_id]['sku'] = $baseProduct->sku;
                $stores[$spec_id]['ids'] = $baseProduct->specID;
            });

            //生成规格信息
            $relations = GoodsSpecRelation::where('goods_id', $o2oGoods->goods_id)
                ->with('spec', 'specValue')->orderBy('sort', 'asc')->get();

            $grouped = $relations->groupBy('spec_id');

            if ($grouped->count() > 2) {
                return $this->failed('数据错误，无法处理！');
            }

            $sort = 1;

            foreach ($grouped as $key => $item) {
                $specs[$sort]['id'] = $key;

                $relation = $item->first();

                if ($key == 2) {  //如果是颜色
                    $specs[$sort]['label_key'] = 'color';
                } else {  //否则是其他规格
                    $specs[$sort]['label_key'] = 'size';
                }

                $specs[$sort]['label'] = $relation->spec->display_name;

                //存储规格值
                $specs[$sort]['list'] = [];
                foreach ($item as $k => $value) {
                    $list = [];
                    $list['id'] = $value->specValue->id;
                    $list['value'] = $value->specValue->name;
                    $list['spec_img'] = $value->img;
                    $list['alias'] = $value->alias;
                    array_push($specs[$sort]['list'], $list);
                }
                ++$sort;
            }
        }

        return [
            'specs' => $specs,
            'stores' => $stores,
        ];
    }

    /**
     * 根据商品名称或货号获取门店product数据
     *
     * @param $shop_id
     * @param $credentials
     *
     * @return mixed|null
     */
    public function getProductsByCredentials($shop_id, $credentials)
    {
        $products = $this->o2oGoodsProductRepository->scopeQuery(function ($query) use ($shop_id) {
            return $query->where('shop_id', $shop_id);
        })->with(['baseProduct', 'baseGoods', 'O2oGoods'])
            ->whereHas('baseGoods', function ($query) use ($credentials) {
                $query = $query->where('name', 'like', '%' . $credentials . '%')
                    ->orWhere('goods_no', 'like', '%' . $credentials . '%');

                return $query->orderBy('created_at', 'desc');
            })->get();

        if ($products->count() > 0) {

            foreach ($products as $item) {
                if ($item->baseProduct) {
                    $specValue = GoodsSpecRelation::where('goods_id', $item->goods_id)
                        ->whereIn('spec_value_id', $item->baseProduct['specID'])
                        ->get()->pluck('alias')->toArray();

                    $item->spec_text = $specValue;

                    /*品牌折扣*/
                    $item->user_discount = 100;
                    $brand_id = $item->baseGoods->brand_id;
                    if ($shopBrand = ShopBrandRelation::where('brand_id', $brand_id)->where('shop_id', $item->shop_id)->first()) {
                        $item->user_discount = $shopBrand->discount;
                    }
                }
            }

            return $products;
        }

        return new Collection();
    }

    /**
     * 根据SKU编码获取门店product数据
     * @param $shop_id
     * @param $credentials
     * @return Collection|mixed
     */
    public function getProductsBySku($shop_id, $credentials)
    {
        $product = $this->o2oGoodsProductRepository->scopeQuery(function ($query) use ($shop_id) {
            return $query->where('shop_id', $shop_id);
        })->with(['baseProduct', 'baseGoods', 'O2oGoods'])
            ->whereHas('baseProduct', function ($query) use ($credentials) {
                $query = $query->where('sku', 'like', '%' . $credentials . '%');
                return $query->orderBy('created_at', 'desc');
            })->first();


        if ($product) {
                if ($product->baseProduct) {
                    $specValue = GoodsSpecRelation::where('goods_id', $product->goods_id)
                        ->whereIn('spec_value_id', $product->baseProduct['specID'])
                        ->get()->pluck('alias')->toArray();

                    $product->spec_text = $specValue;

                    /*品牌折扣*/
                    $product->user_discount = 100;
                    $brand_id = $product->baseGoods->brand_id;
                    if ($shopBrand = ShopBrandRelation::where('brand_id', $brand_id)->where('shop_id', $product->shop_id)->first()) {
                        $product->user_discount = $shopBrand->discount;
                    }
                }
            return $product;
        }

        return null;
    }

    /**
     * 根据搜索条件获取门店商品信息
     * @param $shop_id
     * @param $credentials
     * @param $ids
     * @return array
     */
    public function getGoodsByCredentials($shop_id, $credentials, $ids)
    {
        $goods = $this->o2oGoodsRepository->scopeQuery(function ($query) use ($shop_id, $ids) {
            return $query->where('shop_id', $shop_id);
        })->with('goods')
            ->whereHas('goods', function ($query) use ($credentials, $ids) {
                $query = $query->where('name', 'like', '%' . $credentials . '%')
                    ->orWhere('goods_no', 'like', '%' . $credentials . '%');

                if (count($ids)) {
                    $query = $query->whereIn('id', $ids);
                }

                return $query->orderBy('created_at', 'desc');
            })->get();

        if ($goods->count()) {
            return $goods->toArray();
        }
        return [];
    }

    public function getShopGoodsByCredentials($shop_id, $credentials, $ids)
    {
        $goods = $this->baseRepository->scopeQuery(function ($query) use ($credentials, $shop_id, $ids) {
            if ($credentials) {
                $query = $query->where('name', 'like', '%' . $credentials . '%')
                    ->orWhere('goods_no', 'like', '%' . $credentials . '%');
            }

            if (count($ids)) {
                $query = $query->whereIn('id', $ids);
            }

            return $query->orderBy('created_at', 'desc');
        })->get();

        if ($goods->count()) {
            return $goods->toArray();
        }
        return [];
    }

    /**
     * 退货的加库存
     * @param $refund
     * @param $shop_id
     */
    public function refundAddStore($refund, $shop_id)
    {
        foreach ($refund->items as $item) {
            $num = $item->quantity;
            $item = $item->orderItem;
            $o2oGoodsProduct = O2oGoodsProducts::where('goods_id', $item->item_meta['detail_id'])
                ->where('shop_id', $shop_id)->where('product_id', $item->item_id)->first();


            $o2oGoodsProduct->store_nums = $o2oGoodsProduct->store_nums + $num;
            $o2oGoodsProduct->save();

            $o2oGoods = $o2oGoodsProduct->O2oGoods()->where('id', $o2oGoodsProduct->o2o_goods_id)->first();
            $o2oGoods->store_nums = $o2oGoods->store_nums + $num;
            $o2oGoods->save();

            $specID = $o2oGoodsProduct->baseProduct->specID;
            $spec0 = SpecsValue::find($specID[0]);
            $spec1 = SpecsValue::find($specID[1]);
            if ($spec0->spec_id == 1) {
                $color = $spec1->name;
                $color_id = $specID[1];
                $size = $spec0->name;
                $size_id = $specID[0];
            } elseif ($spec1->spec_id == 1) {
                $color = $spec0->name;
                $color_id = $specID[0];
                $size = $spec1->name;
                $size_id = $specID[1];
            }

            $this->stockRecordRepository->create([
                'shop_id' => $shop_id,
                'item_id' => $item->item_id,
                'item_type' => GoodsProduct::class,
                'type' => StockRecord::STORE_RETURNS,
                'business_type' => Refund::class,
                'business_type_id' => $refund->id,
                'change_count' => $item->quantity,
                'current_stock' => $o2oGoodsProduct->store_nums,
                'goods_id' => $o2oGoodsProduct->baseGoods->id,
                'meta' => [
                    'goods_name' => $o2oGoodsProduct->baseGoods->name,
                    'goods_id' => $o2oGoodsProduct->baseGoods->id,
                    'goods_no' => $o2oGoodsProduct->baseGoods->goods_no,
                    'sku' => $o2oGoodsProduct->baseProduct->sku,
                    'color' => $color,
                    'color_id' => $color_id,
                    'size' => $size,
                    'size_id' => $size_id,
                ],
            ]);
        }
    }

    /**
     * 换货的减库存
     * @param $order
     * @param $shop_id
     * @throws \Exception
     */
    public function exchangeReduceStore($order, $shop_id)
    {
        if (!$order) return;

        foreach ($order->getItems() as $item) {
            $o2oGoodsProduct = O2oGoodsProducts::where('goods_id', $item->item_meta['detail_id'])
                ->where('shop_id', $shop_id)->where('product_id', $item->item_id)->first();

            if ($o2oGoodsProduct->store_nums < $item->quantity) {
                throw new \Exception('商品：' . $item->item_name . ' ' . $item->item_meta['spec_text'] . '库存不足');
                break;
            }

            $o2oGoodsProduct->store_nums = $o2oGoodsProduct->store_nums - $item->quantity;
            $o2oGoodsProduct->save();

            $o2oGoods = $o2oGoodsProduct->O2oGoods()->where('id', $o2oGoodsProduct->o2o_goods_id)->first();
            $o2oGoods->store_nums = $o2oGoods->store_nums - $item->quantity;
            $o2oGoods->save();

            $specID = $o2oGoodsProduct->baseProduct->specID;
            $spec0 = SpecsValue::find($specID[0]);
            $spec1 = SpecsValue::find($specID[1]);
            if ($spec0->spec_id == 1) {
                $color = $spec1->name;
                $color_id = $specID[1];
                $size = $spec0->name;
                $size_id = $specID[0];
            } elseif ($spec1->spec_id == 1) {
                $color = $spec0->name;
                $color_id = $specID[0];
                $size = $spec1->name;
                $size_id = $specID[1];
            }

            $this->stockRecordRepository->create([
                'shop_id' => $shop_id,
                'item_id' => $item->item_id,
                'item_type' => GoodsProduct::class,
                'type' => StockRecord::STORE_SALES,
                'business_type' => Order::class,
                'business_type_id' => $order->id,
                'change_count' => -$item->quantity,
                'current_stock' => $o2oGoodsProduct->store_nums,
                'goods_id' => $o2oGoodsProduct->baseGoods->id,
                'meta' => [
                    'goods_name' => $o2oGoodsProduct->baseGoods->name,
                    'goods_id' => $o2oGoodsProduct->baseGoods->id,
                    'goods_no' => $o2oGoodsProduct->baseGoods->goods_no,
                    'sku' => $o2oGoodsProduct->baseProduct->sku,
                    'color' => $color,
                    'color_id' => $color_id,
                    'size' => $size,
                    'size_id' => $size_id,
                ],
            ]);
        }
    }


}